package com.lehecai.core.lottery.fetcher.lotterydraw.impl.worker;

import com.lehecai.core.lottery.LotteryType;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDraw;
import com.lehecai.core.util.CharsetConstant;
import com.lehecai.core.util.CoreDateUtils;
import com.lehecai.core.util.CoreFetcherUtils;
import org.apache.commons.lang.StringUtils;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.*;
import org.htmlparser.util.NodeList;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 重庆11选5 开奖结果抓取
 *
 * 历史地址: http://www.cqlottery.gov.cn/jsps/11x5/index.jsp
 * @author Sunshow
 *
 */
public class LotteryDrawFetch558WorkerOfficial extends AbstractLotteryDrawFetchWorker {

    private final static String URL_HISTORY = "http://www.cqlottery.gov.cn/dwr/exec/lotteryInfo.get11x5AwardInfo.dwr";

	public LotteryDrawFetch558WorkerOfficial() {
		super(LotteryType.CQ11X5);
	}
	
	@Override
	public LotteryDraw fetchResultDetail(String phase) {
        LotteryType lotteryType = this.getLotteryType();

        String fetchUrl = this.getResultDetailUrl(phase);
        if (StringUtils.isEmpty(fetchUrl)) {
            logger.error("==详细页面==抓取=={}==期号：{}==详细地址不存在，返回null", lotteryType.getName(), phase);
            return null;
        }

        Map<String, String> headerParams = new HashMap<String, String>();
        headerParams.put("Referer", "http://www.cqlottery.gov.cn/");
        headerParams.put("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8");
        headerParams.put("Content-Type", "text/plain; charset=UTF-8");

        Map<String, String> bodyParams = new HashMap<String, String>();
        bodyParams.put("callCount", "1");
        bodyParams.put("c0-scriptName", "lotteryInfo");
        bodyParams.put("c0-methodName", "get11x5AwardInfo");

        long currentTimeMillis = System.currentTimeMillis();

        bodyParams.put("c0-id", (currentTimeMillis % 1000) + "_" + currentTimeMillis);
        bodyParams.put("c0-param0", "string:FCCQ11X5");

        String fetchDate;
        if (StringUtils.isBlank(phase)) {
            fetchDate = CoreDateUtils.formatDate(new Date());
        } else {
            fetchDate = CoreDateUtils.formatDate("20" + phase.substring(0, 6), "yyyyMMdd", CoreDateUtils.DATE);
        }
        bodyParams.put("c0-param1", "string:" + fetchDate);
        bodyParams.put("xml", "true");

        String data = CoreFetcherUtils.URLPostWithHeaderAndBodyParams(fetchUrl, headerParams, bodyParams, null, CharsetConstant.CHARSET_UTF8);
        if (StringUtils.isEmpty(data)) {
            logger.error("data is null or 404 Not Found, url={}", fetchUrl);
            return null;
        }

        data = StringUtils.replace(StringUtils.substringBetween(data, "var s1=\"", "\";s0"), "\\\"", "\"");

        Parser parser;
        try {
            parser = Parser.createParser(data, CharsetConstant.CHARSET_UTF8);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            logger.error("解析html出错, data={}", data);
            return null;
        }

        // 找到开奖号码所在的table
        NodeList drawRowNodeList = null;
        try {
            NodeFilter headFilter = new AndFilter(new TagNameFilter("TD"), new NotFilter(new HasAttributeFilter("background")));
            NodeFilter drawRowFilter = new HasChildFilter(headFilter);
            drawRowNodeList = parser.extractAllNodesThatMatch(drawRowFilter);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        if (drawRowNodeList == null) {
            logger.error("未找到开奖号码所在的数据区, data={}", data);
            return null;
        }

        LotteryDraw lotteryDraw = new LotteryDraw();
        lotteryDraw.setLotteryType(lotteryType);

        for (int i = 0, imax = drawRowNodeList.size(); i < imax; i ++) {
            Node drawRowNode = drawRowNodeList.elementAt(i);
            NodeList drawResultCellList = null;
            try {
                parser = Parser.createParser(drawRowNode.toHtml(), CharsetConstant.CHARSET_UTF8);
                NodeFilter drawResultCellFilter = new TagNameFilter("TD");
                drawResultCellList = parser.extractAllNodesThatMatch(drawResultCellFilter);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                logger.error("解析开奖结果格式出错, data={}", drawRowNode.toHtml());
            }

            if (drawResultCellList == null || drawResultCellList.size() < 4) {
                logger.error("开奖结果格式不正确, data={}", drawRowNode.toHtml());
                continue;
            }

            String fetchedPhase = StringUtils.trim(drawResultCellList.elementAt(0).toPlainTextString());
            if (StringUtils.isNotBlank(phase)) {
                if (!phase.equals(fetchedPhase)) {
                    continue;
                }
            }

            lotteryDraw.setPhase(fetchedPhase);
            lotteryDraw.setTimeDraw(StringUtils.trim(drawResultCellList.elementAt(1).toPlainTextString()));

            String fetchedResultStr = StringUtils.trim(drawResultCellList.elementAt(3).toPlainTextString());
            lotteryDraw.setResult(StringUtils.replace(fetchedResultStr, " ", ","));

            if (StringUtils.isBlank(phase)) {
                break;
            }
        }

        if (lotteryDraw.getPhase() == null) {
            logger.error("未抓取到彩期数据或彩期不匹配");
            return null;
        }

        return lotteryDraw;
	}

	@Override
	public LotteryDraw fetchResult(String phase) {
		return this.fetchResultDetail(phase);
	}

	@Override
	protected String getResultDetailUrl(String phase) {
		return URL_HISTORY;
	}

	@Override
	protected String getResultUrl(String phase) {
		return null;
	}
}
